feat(telemetry): add OTLP export writer#961
Open
EhabY wants to merge 4 commits into
Open
Conversation
199d2e7 to
3a29ac9
Compare
ab7dcf4 to
acadd7e
Compare
3a29ac9 to
eb776a7
Compare
acadd7e to
29c269d
Compare
ba095a9 to
8066586
Compare
5a186aa to
5ee4862
Compare
3d77d32 to
c9c3b74
Compare
5ee4862 to
539131f
Compare
c9c3b74 to
9c5a19d
Compare
539131f to
fe6675e
Compare
9c5a19d to
914025b
Compare
fe6675e to
94ac895
Compare
EhabY
added a commit
that referenced
this pull request
May 21, 2026
- Move src/telemetry/export/writers.ts to writers/json.ts and the
matching test to writers/json.test.ts. The writer keeps the same
shape; the doc comment is tightened and the test drops a
redundant atomic-failure assertion already covered by
writeAtomically's own tests.
- Extract parseTelemetryTimestampMs from range.ts's
isTimestampInRange so other export writers can reuse it.
- Add a trivial asyncIterable test helper to test/mocks/.
- Inline the duplicated `vi.mock("node:fs", ...)` /
`vi.mock("node:fs/promises", ...)` factory pair (9 lines per file)
as a 2-line dynamic import in the affected test files.
Upstream-compatible groundwork for the OTLP writer branch (#961);
isolates move + helper-extraction churn so that PR's diff stays
focused on OTLP-specific work.
55cccf2 to
71bcce7
Compare
EhabY
added a commit
that referenced
this pull request
May 21, 2026
- Move src/telemetry/export/writers.ts to writers/json.ts and the
matching test to writers/json.test.ts. The writer keeps the same
shape; the doc comment is tightened and the test drops a
redundant atomic-failure assertion already covered by
writeAtomically's own tests.
- Extract parseTelemetryTimestampMs from range.ts's
isTimestampInRange so other export writers can reuse it.
- Add a trivial asyncIterable test helper to test/mocks/.
- Inline the duplicated `vi.mock("node:fs", ...)` /
`vi.mock("node:fs/promises", ...)` factory pair (9 lines per file)
as a 2-line dynamic import in the affected test files.
Upstream-compatible groundwork for the OTLP writer branch (#961);
isolates move + helper-extraction churn so that PR's diff stays
focused on OTLP-specific work.
034f5bc to
5a9edee
Compare
7ce5f22 to
d9f955a
Compare
1671ea2 to
5cbd8ba
Compare
EhabY
added a commit
that referenced
this pull request
May 21, 2026
- Move src/telemetry/export/writers.ts to writers/json.ts and the
matching test to writers/json.test.ts. The writer keeps the same
shape; the doc comment is tightened and the test drops a
redundant atomic-failure assertion already covered by
writeAtomically's own tests.
- Extract parseTelemetryTimestampMs from range.ts's
isTimestampInRange so other export writers can reuse it.
- Add a trivial asyncIterable test helper to test/mocks/.
- Inline the duplicated `vi.mock("node:fs", ...)` /
`vi.mock("node:fs/promises", ...)` factory pair (9 lines per file)
as a 2-line dynamic import in the affected test files.
Upstream-compatible groundwork for the OTLP writer branch (#961);
isolates move + helper-extraction churn so that PR's diff stays
focused on OTLP-specific work.
5cbd8ba to
d8a9b52
Compare
d9f955a to
f7308bf
Compare
- Restructure: writers.ts → writers/json.ts; combine OTLP mapping and writer into writers/otlp.ts; lift signal classification into export/signal.ts. - Group all records of each signal under a single Resource block per file (was one Resource per event), matching the OTLP spec's recommended shape and shrinking exports at scale. - Adopt OTLP enums from @opentelemetry/api + api-logs; document the +1 wire offset on SpanKind. - Tighten the public surface: only writeOtlpZipExport and OtlpExportCounts are exported; record mappers are module-private. - Hoist per-event metric attributes once; single-pass partition of http.requests measurements into counts and gauges. - Share parseTelemetryTimestampMs between range.ts and the OTLP writer's nanos conversion (was duplicated with identical error). - Extract asyncIterable test helper to test/mocks/; inline the memfs vi.mock pair across affected test files. - Tests now exercise the public API only, dropping side-effect assertions about staging cleanup and atomic semantics already covered by writeAtomically's own tests.
Wire-format fixes: - Switch http.requests count_* sums from DELTA to CUMULATIVE temporality (Prom/Mimir/Grafana Cloud reject the delta+sum combination). - Maintain per-series running totals across the export, anchored at the first observed window's startTimeUnixNano. - Suppress zero-cumulative counters so routes that never errored don't ship empty data points. Semantic-convention compliance: - Use OTel-standard `service.instance.id` (was `coder.session.id`) and `host.id` (was `coder.machine.id`) for portability with OTel-aware backends. The previous vendor keys were pure aliases. - Add `schemaUrl` to each ResourceLogs/ResourceSpans/ResourceMetrics container and each scope container. - Stamp scope.version with the extension version.
f7308bf to
6ac4715
Compare
Group OTLP code into src/telemetry/export/writers/otlp/ with one file per concern, and hoist metric classification to src/telemetry/export/metrics.ts so it can be shared by future writers. Layout: - metrics.ts: domain (isMetricEvent, describeMetricEvent, units) - otlp/writer.ts: public API + orchestration (signal routing, packZip) - otlp/envelope.ts: streaming JSON envelope writer + error wrapping - otlp/records.ts: log/span/metric record builders + helpers - otlp/types.ts: OTLP wire-format interfaces (pinned to proto v1.10.0) Safety fixes surfaced by the layer split: - envelope: listen for stream 'error' events so failed opens reject pending writes instead of hanging; close() is idempotent; suffix-write failures during close are labeled as close failures. - writer: on loop failure, use Promise.allSettled to close streams without masking the original error. - records: coerce NaN/Infinity numeric inputs to 0n instead of throwing from BigInt(); clamp startTimeUnixNano <= timeUnixNano for out-of-order events; include eventName in the cumulative-series key. Each layer has its own test file; total grows from 99 to 131 cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.otlp.zipexport writing with POST-readylogs.json,traces.json, andmetrics.jsonRefs #903.
Stack: 3 / 4. Base: #960. Next: #953.
Review follow-up
Validation
pnpm test:extension ./test/unit/telemetry/export/range.test.ts ./test/unit/telemetry/export/files.test.ts ./test/unit/telemetry/export/writers.test.tspnpm typecheckpnpm lintpnpm format:checkGenerated by Coder Agents.